﻿using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Text.Json;

namespace FeishuWorkflowService.Services
{
    /// <summary>
    /// 虚拟控件构建器，通过配置文件动态创建和管理虚拟控件对象
    /// </summary>
    public class VirtualControlBuilder
    {
        private readonly Dictionary<string, ControlConfig> _controlConfigs;
        private readonly JsonSerializerOptions _jsonOptions = new()
        {
            WriteIndented = true,
            PropertyNameCaseInsensitive = true,
            Converters = { new ExpandoObjectConverter() }
        };

        public VirtualControlBuilder(string configPath)
        {
            if (!File.Exists(configPath))
                throw new FileNotFoundException("配置文件不存在", configPath);

            var json = File.ReadAllText(configPath);
            var configRoot = JsonSerializer.Deserialize<ControlConfigRoot>(json, _jsonOptions);

            if (configRoot?.Controls == null || configRoot.Controls.Count == 0)
                throw new InvalidDataException("配置文件格式不正确或未包含控件定义");

            _controlConfigs = new Dictionary<string, ControlConfig>();
            foreach (var control in configRoot.Controls)
            {
                if (!_controlConfigs.ContainsKey(control.Type))
                    _controlConfigs.Add(control.Type, control);
            }
        }

        /// <summary>
        /// 创建指定类型的虚拟控件
        /// </summary>
        public dynamic CreateVirtualControl(string controlType)
        {
            if (!_controlConfigs.TryGetValue(controlType, out var config))
                throw new ArgumentException($"未知的控件类型: {controlType}");

            dynamic control = new ExpandoObject();
            var properties = (IDictionary<string, object>)control;

            foreach (var propConfig in config.Properties)
            {
                object value = CreatePropertyValue(propConfig);
                properties[propConfig.Name] = value;
            }

            return control;
        }

        /// <summary>
        /// 获取虚拟控件的属性值（支持嵌套属性，使用.分隔，如"value.start"）
        /// </summary>
        public object GetPropertyValue(dynamic control, string propertyPath)
        {
            if (control == null)
                throw new ArgumentNullException(nameof(control));
            if (string.IsNullOrEmpty(propertyPath))
                throw new ArgumentException("属性路径不能为空", nameof(propertyPath));

            var pathSegments = propertyPath.Split('.');
            object current = control;

            foreach (var segment in pathSegments)
            {
                if (current is IDictionary<string, object> dict)
                {
                    if (!dict.TryGetValue(segment, out current))
                        throw new KeyNotFoundException($"属性不存在: {segment}");
                }
                else
                {
                    throw new InvalidOperationException($"无法访问属性 {segment}，当前对象不是字典类型");
                }
            }

            return current;
        }

        /// <summary>
        /// 设置虚拟控件的属性值（支持嵌套属性，使用.分隔，如"value.start"）
        /// </summary>
        public void SetPropertyValue(dynamic control, string propertyPath, object value)
        {
            if (control == null)
                throw new ArgumentNullException(nameof(control));
            if (string.IsNullOrEmpty(propertyPath))
                throw new ArgumentException("属性路径不能为空", nameof(propertyPath));

            var pathSegments = propertyPath.Split('.');
            object current = control;

            // 遍历到最后一个属性的父对象
            for (int i = 0; i < pathSegments.Length - 1; i++)
            {
                var segment = pathSegments[i];
                if (current is IDictionary<string, object> dict)
                {
                    if (!dict.TryGetValue(segment, out current))
                        throw new KeyNotFoundException($"属性不存在: {segment}");
                }
                else
                {
                    throw new InvalidOperationException($"无法访问属性 {segment}，当前对象不是字典类型");
                }
            }

            // 设置最终属性值
            if (current is IDictionary<string, object> parentDict)
            {
                parentDict[pathSegments[^1]] = value;
            }
            else
            {
                throw new InvalidOperationException("父对象不是字典类型，无法设置属性值");
            }
        }

        /// <summary>
        /// 将虚拟控件序列化为JSON字符串
        /// </summary>
        public string Serialize(dynamic control)
        {
            if (control == null)
                throw new ArgumentNullException(nameof(control));

            return JsonSerializer.Serialize(control, _jsonOptions);
        }

        /// <summary>
        /// 将JSON字符串反序列化为虚拟控件
        /// </summary>
        public dynamic Deserialize(string json)
        {
            if (string.IsNullOrEmpty(json))
                throw new ArgumentException("JSON字符串不能为空", nameof(json));

            return JsonSerializer.Deserialize<ExpandoObject>(json, _jsonOptions);
        }

        /// <summary>
        /// 创建属性值（处理基础类型、集合和嵌套对象）
        /// </summary>
        private object CreatePropertyValue(PropertyDefinition propConfig)
        {
            // 如果有固定值，则使用固定值
            if (propConfig.FixedValue != null)
            {
                return propConfig.FixedValue;
            }

            // 根据类型创建对应的值
            return propConfig.Type switch
            {
                "string" => string.Empty,
                "int" => 0,
                "float" => 0.0f,
                "DateTimeOffset" => DateTimeOffset.MinValue,
                "List<string>" => new List<string>(),
                "List<List<dynamic>>" => new List<List<dynamic>>(),
                "object" or "List<object>" => CreateNestedObject(propConfig),
                _ => null
            };
        }

        /// <summary>
        /// 创建嵌套对象或对象列表
        /// </summary>
        private object CreateNestedObject(PropertyDefinition propConfig)
        {
            if (propConfig.NestedProperties == null || propConfig.NestedProperties.Count == 0)
            {
                return new ExpandoObject();
            }

            // 如果是列表类型，创建列表并添加一个初始对象
            if (propConfig.Type == "List<object>")
            {
                var list = new List<object>();
                var initialObject = new ExpandoObject() as IDictionary<string, object>;

                foreach (var nestedProp in propConfig.NestedProperties)
                {
                    initialObject[nestedProp.Name] = CreatePropertyValue(nestedProp);
                }

                list.Add(initialObject);
                return list;
            }

            // 创建单个嵌套对象
            var nestedObj = new ExpandoObject() as IDictionary<string, object>;
            foreach (var nestedProp in propConfig.NestedProperties)
            {
                nestedObj[nestedProp.Name] = CreatePropertyValue(nestedProp);
            }

            return nestedObj;
        }
    }

    // 配置文件解析所需的模型类
    public class ControlConfigRoot
    {
        public List<ControlConfig> Controls { get; set; } = new();
    }

    public class ControlConfig
    {
        public string Type { get; set; } = string.Empty;
        public List<PropertyDefinition> Properties { get; set; } = new();
    }

    public class PropertyDefinition
    {
        public string Name { get; set; } = string.Empty;
        public string Type { get; set; } = string.Empty;
        public object? FixedValue { get; set; }
        public List<PropertyDefinition>? NestedProperties { get; set; }
    }
}
